﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Configuration.Provider;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Web.Security;
using System.Web.UI.DataVisualization.Charting;
using SCRUM.Core.BusinessObjects;

namespace SCRUM.Core.DataProviders
{
	/// <summary>
	/// Interface for all data providers
	/// </summary>
	/// <remarks>
	/// Every data provider has to inherit from this class.
	/// </remarks>
    public abstract class DataProvider : ProviderBase
    {
        #region [ Project ]
        /// <summary>
        /// Creates new Project.
        /// </summary>
        /// <param name="project">The specific project.</param>
        /// <returns>Created project with ID set</returns>
        public abstract Project CreateProject(Project project);

		/// <summary>
		/// Updates the project.
		/// </summary>
		/// <param name="project">The specific project.</param>
        public abstract void UpdateProject(Project project);

        /// <summary>
        /// Deletes the project.
        /// </summary>
        /// <param name="id">The specific project id.</param>
        public abstract void DeleteProject(int id);

		/// <summary>
		/// Get projects from page with projectID and pageSize
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="teamID">The team ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Project> GetAllProjects(int projectID, int releaseID, int teamID);

		/// <summary>
		/// Get all projects.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Project> GetAllProjects();

        /// <summary>
        ///  Returns project according to id
        /// </summary>
        /// <param name="projectId">id of project</param>
        /// <returns>Project with specified ID.</returns>
        public abstract Project GetProjectById(int projectId);

        /// <summary>
        /// Gets the project by release.
        /// </summary>
        /// <param name="releaseID">The release.</param>
        /// <returns>project the release belongs to</returns>
        public abstract Project GetProjectByReleaseID(int releaseID);

        /// <summary>
        /// Gets the project by team ID.
        /// </summary>
        /// <param name="teamID">The team ID.</param>
        /// <returns>Project the team is working at.</returns>
        public abstract Project GetProjectByTeam(int teamID);
        #endregion

        #region [ Release ]
        /// <summary>
        /// Creates new Release for project.
        /// </summary>
        /// <param name="release">The specific release.</param>
        /// <param name="projectId">Id of project to add release to.</param>
        /// <returns>Created release</returns>
        public abstract Release CreateRelease(Release release, int projectId);

        /// <summary>
        /// Updates the release.
        /// </summary>
        /// <param name="release">The specific release.</param>
        /// <param name="projectId">Id of project to add release to.</param>
        public abstract void UpdateRelease(Release release, int projectId);

        /// <summary>
        /// Deletes the release.
        /// </summary>
        /// <param name="releaseId">The specific release id.</param>
        public abstract void DeleteRelease(int releaseId);

		/// <summary>
		/// Gets all releases. if any of parameters is -1 then it is not used in search
		/// </summary>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="projectID">The project ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Release> GetAllReleases(int releaseID, int projectID, int sprintID);

		/// <summary>
		/// Get all releases.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Release> GetAllReleases();

		/// <summary>
		/// Returns release according to id
		/// </summary>
		/// <param name="releaseId">id of release</param>
		/// <returns>release details</returns>
        public abstract Release GetReleaseById(int releaseId);

        /// <summary>
        /// Gets the release by sprint ID.
        /// </summary>
        /// <param name="sprintID">Id of the sprint.</param>
        /// <returns>release containing that sprint</returns>
        public abstract Release GetReleaseBySprintID(int sprintID);

		/// <summary>
		/// Get all releases for specific project.
		/// </summary>
		/// <param name="projectID">Id of project</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Release> GetAllReleasesForProject(int projectID);
        #endregion

        #region [ Sprint ]
        /// <summary>
        /// Creates new sprint.
        /// </summary>
        /// <param name="sprint">The specific sprint.</param>
        /// <param name="releaseId">Release id to add sprint to.</param>
        /// <returns>Created sprint</returns>
        public abstract Sprint CreateSprint(Sprint sprint, int releaseId);

        /// <summary>
        /// Updates the sprint.
        /// </summary>
        /// <param name="sprint">The specific sprint.</param>
        /// <param name="releaseId">id of release that sprint is in</param>
        public abstract void UpdateSprint(Sprint sprint, int releaseId);

		/// <summary>
		/// Deletes the sprint.
		/// </summary>
		/// <param name="sprintId">The specific sprint id.</param>
        public abstract void DeleteSprint(int sprintId);

        /// <summary>
        /// Gets the sprint by userStoryID.
        /// </summary>
        /// <param name="userStoryID">ID of the UserStory.</param>
        /// <returns>sprint containing that user story</returns>
        public abstract Sprint GetSprintByUserStoryID(int userStoryID);

		/// <summary>
		/// Get all sprints for specific release.
		/// </summary>
		/// <param name="releaseID">Id of release</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Sprint> GetAllSprintsForRelease(int releaseID);

		/// <summary>
		/// Get all sprints for specific project.
		/// </summary>
		/// <param name="projectID">Id of project</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Sprint> GetAllSprintsForProject(int projectID);

		/// <summary>
		/// Get all sprints.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Sprint> GetAllSprints();

		/// <summary>
		/// Gets all sprints.
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		/// <param name="userStoryID">The user story ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Sprint> GetAllSprints(int projectID, int releaseID, int sprintID, int userStoryID);

		/// <summary>
		/// Gets all future sprints.
		/// </summary>
		/// <returns>List of all task, which did not ended.</returns>
		public abstract IList<Sprint> GetAllFutureSprints();

		/// <summary>
		/// Returns sprint according to id
		/// </summary>
		/// <param name="sprintId">id of sprint</param>
		/// <returns>sprint details</returns>
        public abstract Sprint GetSprintById(int sprintId);
        #endregion

        #region [ UserStory ]
        /// <summary>
        /// Creates new user story.
        /// </summary>
        /// <param name="userStory">The specific user story.</param>
        /// <param name="sprintID">Sprint id to add user story to.</param>
        /// <returns>created user story</returns>
        public abstract UserStory CreateUserStory(UserStory userStory, int? sprintID);

        /// <summary>
        /// Updates the user story.
        /// </summary>
        /// <param name="userStory">The specific user story.</param>
        /// <param name="sprintID">id of sprint that user story is in</param>
        public abstract void UpdateUserStory(UserStory userStory, int sprintID);

        /// <summary>
        /// Updates the user story.
        /// </summary>
        /// <param name="userStory">The specific user story.</param>
        public abstract void UpdateUserStory(UserStory userStory);

        /// <summary>
        /// Deletes the user story.
        /// </summary>
        /// <param name="userStoryID">The specific user story.</param>
        public abstract void DeleteUserStory(int userStoryID);            

        /// <summary>
        ///  Returns user story according to id
        /// </summary>
        /// <param name="userStoryID">id of user story</param>
        /// <returns>user story details</returns>
        public abstract UserStory GetUserStoryByID(int userStoryID);

		/// <summary>
		/// Gets the user story by BLI ID.
		/// </summary>
		/// <param name="bliID">ID of the BLI.</param>
		/// <returns>user story containing that BLI</returns>
        public abstract UserStory GetUserStoryByBliID(int bliID);

		/// <summary>
		/// Get all user stories for specific sprint.
		/// </summary>
		/// <param name="sprintID">Id of sprint</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<UserStory> GetAllUserStoriesForSprint(int sprintID);

		/// <summary>
		/// Get all user stories for specific release.
		/// </summary>
		/// <param name="releaseID">Id of release</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<UserStory> GetAllUserStoriesForRelease(int releaseID);

		/// <summary>
		/// Get all user stories for specific project.
		/// </summary>
		/// <param name="projectID">Id of project</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<UserStory> GetAllUserStoriesForProject(int projectID);

		/// <summary>
		/// Get all user stories.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<UserStory> GetAllUserStories();

		/// <summary>
		/// Gets all user stories.
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		/// <param name="userStoryID">The user story ID.</param>
		/// <param name="bliID">The bli ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<UserStory> GetAllUserStories(int projectID, int releaseID, int sprintID, int userStoryID, int bliID);

		/// <summary>
		/// Updates the sprint of the user story.
		/// </summary>
		/// <param name="userStoryID">The user story ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		public abstract void UpdateUserStorySprint(int userStoryID, int? sprintID);

		/// <summary>
		/// Gets the unassigned stories.
		/// </summary>
		/// <returns>List of unassigned userstories.</returns>
		public abstract IList<UserStory> GetUnassignedStories();
        #endregion

	    #region [ BLI ]
        /// <summary>
        /// Creates new BLI.
        /// </summary>
        /// <param name="bli">The specific bli.</param>
        /// <param name="userStoryID">User story id to add BLI to.</param>
        /// <returns>Bli with ID</returns>
        public abstract BLI CreateBli(BLI bli, int userStoryID);

        /// <summary>
        /// Updates the BLI.
        /// </summary>
        /// <param name="bli">The specific BLI.</param>
        /// <param name="sprintID">id of user story that BLI is in</param>
        public abstract void UpdateBli(BLI bli, int sprintID);

        /// <summary>
        /// Deletes the BLI.
        /// </summary>
        /// <param name="bliID">The specific BLI.</param>
        public abstract void DeleteBli(int bliID);

		/// <summary>
		/// Returns BLI according to id
		/// </summary>
		/// <param name="bliID">ID of the BLI</param>
		/// <returns>BLI details</returns>
        public abstract BLI GetBliByID(int bliID);

        /// <summary>
        /// Gets all types of Bli
        /// </summary>
        /// <returns>list of Bli types</returns>
        public abstract NameValueCollection GetBliTypes();

		/// <summary>
		/// Get all BLIs for specific user story.
		/// </summary>
		/// <param name="userStoryID">Id of user story</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetAllBlisForUserStory(int userStoryID);

        /// <summary>
        /// Returns BLI according to task 
        /// </summary>
        /// <param name="task">Task to search BLI for</param>
        /// <returns>Backlog item</returns>
        public abstract BLI GetBliByTask(Task task);

		/// <summary>
		/// Get all BLIs for specific sprint.
		/// </summary>
		/// <param name="sprintID">Id of sprint</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetAllBlisForSprint(int sprintID);

		/// <summary>
		/// Get all BLIs for specific release.
		/// </summary>
		/// <param name="releaseID">Id of release</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetAllBlisForRelease(int releaseID);

		/// <summary>
		/// Get all BLIs for specific project.
		/// </summary>
		/// <param name="projectID">Id of project</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetAllBlisForProject(int projectID);

		/// <summary>
		/// Get all BLIs.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetAllBlis();

		/// <summary>
		/// Gets the blis.
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		/// <param name="userStoryID">The user story ID.</param>
		/// <param name="bliID">The bli ID.</param>
		/// <param name="taskID">The task ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<BLI> GetBlis(int projectID, int releaseID, int sprintID, int userStoryID, int bliID, int taskID);

        #endregion

        #region [ State ]
        /// <summary>
        /// Creates new State.
        /// </summary>
        /// <param name="state">The specific state.</param>
        public abstract void CreateState(State state);

		/// <summary>
		/// Returns state of specific type according to id
		/// </summary>
		/// <param name="id">state id</param>
		/// <param name="type">type of state</param>
		/// <returns>state according to id</returns>
        public abstract State GetStateForType(int id, State.StateTypes type);

        /// <summary>
        /// Updates the State.
        /// </summary>
        /// <param name="state">The specific State.</param>
        public abstract void UpdateState(State state);

        /// <summary>
        /// Deletes the state.
        /// </summary>
        /// <param name="state">The specific state.</param>
        public abstract void DeleteState(State state);

		/// <summary>
		/// Get all states of specific type.
		/// </summary>
		/// <param name="type">Type of state to return</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<State> GetAllStates(State.StateTypes type);

        #endregion

        #region [ Task ]

        /// <summary>
        /// Gets all Tasks for user
        /// </summary>
        /// <param name="userID">ID of user</param>
        /// <returns>All tasks for user</returns>
        public abstract List<Task> GetAllUsersTasks(int userID);

		/// <summary>
		/// Gets all Tasks for bli
		/// </summary>
		/// <param name="bliID">The bli ID.</param>
		/// <returns>All tasks in bli</returns>
        public abstract List<Task> GetAllTasksForBli(int bliID);

		/// <summary>
		/// Gets all tasks for bli in the state.
		/// </summary>
		/// <param name="bli">The bli.</param>
		/// <param name="stateID">The state ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Task> GetAllTasks(BLI bli, int stateID);

		/// <summary>
		/// Gets all tasks.
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <param name="releaseID">The release ID.</param>
		/// <param name="sprintID">The sprint ID.</param>
		/// <param name="userStoryID">The user story ID.</param>
		/// <param name="bliID">The bli ID.</param>
		/// <param name="taskID">The task ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Task> GetAllTasks(int projectID, int releaseID, int sprintID, int userStoryID, int bliID, int taskID);

        /// <summary>
        /// Creates the task.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <param name="inBli">Id of BLI the task is in.</param>
        /// <returns>Created Task</returns>
        public abstract Task CreateTask(Task task, int inBli);

        /// <summary>
        /// Updates the task.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <param name="inBli">Id of BLI the task is in.</param>
        public abstract void UpdateTask(Task task, int inBli);

        /// <summary>
        /// Deletes the task.
        /// </summary>
        /// <param name="taskID">The task ID.</param>
        public abstract void DeleteTask(int taskID);

		/// <summary>
		/// Returns task according to id
		/// </summary>
		/// <param name="taskID">ID of task</param>
		/// <returns>Task with specified ID</returns>
        public abstract Task GetTaskByID(int taskID);

        /// <summary>
        /// Updates the state of the task.
        /// </summary>
        /// <param name="taskID">The task ID.</param>
        /// <param name="state">The state.</param>
        public abstract void UpdateTaskState(int taskID, string state);

        /// <summary>
        /// Removes the associated user from the task.
        /// </summary>
        /// <param name="taskID">The task ID.</param>
        /// <param name="userID">The user ID.</param>
        public abstract void RemoveAssociatedUser(int taskID, int userID);

        /// <summary>
        /// Adds the associated user to the task.
        /// </summary>
        /// <param name="taskID">The task ID.</param>
        /// <param name="userID">The user ID.</param>
        public abstract void AddAssociatedUser(int taskID, int userID);
        #endregion

        #region [ User ]
        /// <summary>
        /// Inserts the user.
        /// </summary>
        /// <param name="user">The specific user.</param>
        public abstract void InsertUser(User user);

        /// <summary>
        /// Updates the user.
        /// </summary>
        /// <param name="user">The specific user.</param>
        public abstract void UpdateUser(User user);

        /// <summary>
        /// Deletes the user.
        /// </summary>
        /// <param name="user">The specific user.</param>
        public abstract void DeleteUser(User user);

        /// <summary>
        /// Gets the users by all specified parameters. if any of parameters is -1 or null it will not be used in search
        /// </summary>
        /// <param name="id">The id.</param>
        /// <param name="login">The login.</param>
        /// <param name="fullname">The fullname.</param>
        /// <param name="email">The email.</param>
        /// <param name="enabled">if set to <c>true</c> [enabled].</param>
        /// <param name="telephone">The telephone.</param>
        /// <param name="im">The im.</param>
        /// <param name="defaultRoleID">The default role ID.</param>
        /// <returns>collection of Users</returns>
        public abstract IList<User> GetUsers(int id, string login, string fullname, string email, bool? enabled, string telephone, string im, int defaultRoleID);

		/// <summary>
		/// Gets users in specified team and role
		/// </summary>
		/// <param name="team">The team.</param>
		/// <param name="role">The role.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<User> GetTeamMembers(Team team, Role role);

        /// <summary>
        /// Gets users associated to the task.
        /// </summary>
        /// <param name="task">The task.</param>
        /// <returns>List of tasks.</returns>
        public abstract IList<User> GetTeamMembers(Task task);

		/// <summary>
		/// Gets the users which can be assigned to the task.
		/// </summary>
		/// <param name="team">The team.</param>
		/// <param name="task">The task.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<User> GetUsersExceptTaskUsers(Team team, Task task);

		/// <summary>
		/// Gets the users which can be assigned to the task.
		/// </summary>
		/// <param name="taskID">The task ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<User> GetUsersExceptTaskUsers(int taskID);

		/// <summary>
		/// Change user's fullname
		/// </summary>
		/// <param name="login">The login.</param>
		/// <param name="fullName">new fullname</param>
		/// <returns>true - if change was successfull</returns>
        public abstract bool ChangeFullName(string login, string fullName);

        /// <summary>
        /// Gets the user by login.
        /// </summary>
        /// <param name="login">The login.</param>
        /// <returns>The user with specific login.</returns>
        public abstract User GetUserByLogin(string login);
 
        #endregion

        #region [ User In Role ]
		/// <summary>
		/// Gets the users from project specified by it's ID
		/// </summary>
		/// <param name="userInRoleID">The user in role ID.</param>
		/// <param name="projectID">The project ID.</param>
		/// <param name="teamID">The team ID.</param>
		/// <returns>collection of users</returns>
        public abstract IList<UserInRole> GetUsersInRole(int userInRoleID, int projectID, int teamID);

        /// <summary>
        /// Adds the user in role.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="roleID">The role ID.</param>
        /// <param name="teamID">The team ID.</param>
        public abstract void AddUserInRole(int userID, int roleID, int teamID);

        /// <summary>
        /// Deletes the user in role.
        /// </summary>
        /// <param name="userInRoleID">The user in role ID.</param>
        public abstract void DeleteUserInRole(int userInRoleID);

        /// <summary>
        /// Edits the user in role.
        /// </summary>
        /// <param name="userInRoleID">The user in role ID.</param>
        /// <param name="userID">new user ID.</param>
        /// <param name="roleID">new role ID.</param>
        /// <param name="teamID">new team ID.</param>
        public abstract void EditUserInRole(int userInRoleID, int userID, int roleID, int teamID);
        #endregion

        #region [ Widget settings ]
        /// <summary>
		/// Saves the widget settings.
		/// </summary>
		/// <param name="widget">The widget</param>
		/// <param name="ws">The widget settings.</param>
		public abstract void SaveWidgetSettings(Widget widget, StringDictionary ws);

        /// <summary>
        /// Saves default widget settings.
        /// </summary>
        /// <param name="widget">The widget</param>
        /// <param name="ws">The widget settings.</param>
        public abstract void SaveDefaultWidgetSettings(Widget widget, StringDictionary ws);

		/// <summary>
		/// Updates the widget setting.
		/// </summary>
		/// <param name="widget">The widget</param>
		/// <param name="key">The widget setting key.</param>
		/// <param name="value">The widget setting value</param>
		public abstract void UpdateWidgetSetting(Widget widget, string key, string value);

		/// <summary>
		/// Loads the widget settings.
		/// </summary>
		/// <param name="widget">The widget.</param>
		/// <returns>Settings of the widget.</returns>
		public abstract StringDictionary LoadWidgetSettings(Widget widget);

		/// <summary>
		/// Saves the widget setting.
		/// </summary>
		/// <param name="widget">Associated widget</param>
		/// <param name="key">Key value to save</param>
		/// <param name="value">The widget setting</param>
		public abstract void SaveWidgetSetting(Widget widget, string key, string value);

		/// <summary>
		/// DeleteWidget the settings.
		/// </summary>
		/// <param name="widget">The widget.</param>
		/// <param name="key">Key value to delete</param>
		public abstract void DeleteSetting(Widget widget, string key);
        #endregion

        #region [ Widgets ]
		/// <summary>
		/// Gets the widget by ID.
		/// </summary>
		/// <param name="id">The identifier.</param>
		/// <returns>Widget with a specified ID.</returns>
		public abstract Widget GetWidgetByID(int id);

		/// <summary>
		/// Gets the widgets for the specified column.
		/// </summary>
		/// <param name="column">The column.</param>
		/// <returns>List of widgets for the specified column.</returns>
		public abstract IList<Widget> GetWidgets(WidgetColumn column);

		/// <summary>
		/// Creates the new instance of widget in widgetColumn for specified user
		/// </summary>
		/// <param name="widgetTypeID">The widget type ID.</param>
		/// <param name="order">The order.</param>
		/// <param name="widgetColumnID">The widget column ID.</param>
		/// <param name="userID">The user ID.</param>
        public abstract void CreateNewWidget(int widgetTypeID, int order, int widgetColumnID, int userID);

        /// <summary>
        /// Deletes the widget.
        /// </summary>
        /// <param name="widget">The widget.</param>
        public abstract void DeleteWidget(Widget widget);

        /// <summary>
        /// Copies the widgets into column.
        /// </summary>
        /// <param name="widgetsToCopy">The widgets to copy.</param>
        /// <param name="columnID">The column ID.</param>
        /// <param name="userID">The user ID.</param>
        public abstract void CopyWidgetsIntoColumn(IList<Widget> widgetsToCopy, int columnID, int userID);
        
        #endregion

        #region [ Widget Type ]
        /// <summary>
        /// Gets all available widget types for user.
        /// </summary>
        /// <param name="user">The user.</param>
        /// <returns>List of Widget types available for user</returns>
        public abstract IList<WidgetType> GetAllAvailableWidgetTypes(User user);

		/// <summary>
		/// Gets all widget types.
		/// </summary>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<WidgetType> GetAllWidgetTypes();

		/// <summary>
		/// Gets the widget rights for specified widgetType ID and role ID
		/// </summary>
		/// <param name="widgetTypeID">The widget type ID.</param>
		/// <param name="roleID">The role ID.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<WidgetRight> GetWidgetRights(int widgetTypeID, int roleID);

		/// <summary>
		/// Gets the widget type by ID.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <returns>Type of the widget.</returns>
        public abstract WidgetType GetWidgetTypeByID(int id);

		/// <summary>
		/// Saves the type of the widget.
		/// </summary>
		/// <param name="widgetType">Type of the widget.</param>
        public abstract void SaveWidgetType(WidgetType widgetType);

        /// <summary>
        /// Creates new type of the widget with specified parameters
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="description">The description.</param>
        /// <param name="enabled">if set to <c>true</c> [enabled].</param>
        public abstract void CreateWidgetType(string name, string description, bool enabled);
        #endregion

        #region [ Widget Rights ]
        /// <summary>
        /// Updates the write right.
        /// </summary>
        /// <param name="rightID">The right ID.</param>
        /// <param name="right">if set to <c>true</c> [right].</param>
        public abstract void UpdateWriteRight(int rightID, bool right);

        /// <summary>
        /// Adds the view right for specified roleID and widgetTypeID
        /// </summary>
        /// <param name="roleID">The role ID.</param>
        /// <param name="widgetTypeID">The widget type ID.</param>
        public abstract void AddViewRight(int roleID, int widgetTypeID);

        /// <summary>
        /// Removes the view right for specified right ID
        /// </summary>
        /// <param name="rightID">The right ID.</param>
        public abstract void RemoveViewRight(int rightID);

        /// <summary>
        /// Gets the user right for widget.
        /// </summary>
        /// <param name="currentUser">The current user.</param>
        /// <param name="widgetTypeID">The widget type ID.</param>
        /// <returns></returns>
        public abstract UserRightForWidget GetUserRightForWidget(int currentUser, int widgetTypeID);
        #endregion

        #region [ Team ]
        /// <summary>
        /// Gets all teams.
        /// </summary>
        /// <returns>List of all teams.</returns>
        public abstract List<Team> GetAllTeams();

		/// <summary>
		/// Gets all teams.
		/// </summary>
		/// <param name="projectID">The project ID.</param>
		/// <returns>List of teams associated to the project.</returns>
        public abstract IList<Team> GetAllTeams(int projectID);

		/// <summary>
		/// Gets the team.
		/// </summary>
		/// <param name="id">The id.</param>
		/// <returns>Team with specified id.</returns>
        public abstract Team GetTeam(int id);

        /// <summary>
        /// Gets the team.
        /// </summary>
        /// <param name="user">The user of the team.</param>
        /// <returns>Team for specified user.</returns>
        public abstract IList<Team> GetTeamForUser(User user);

		/// <summary>
		/// Creates new team in specified project with specified team name
		/// </summary>
		/// <param name="teamName">Name of new team.</param>
		/// <param name="projectID">new team's project ID.</param>
		/// <returns>Team with specified team name and project ID.</returns>
        public abstract Team CreateTeam(string teamName, int projectID);

        /// <summary>
        /// Deletes the team with specified ID.
        /// </summary>
        /// <param name="teamID">The team ID.</param>
        public abstract void DeleteTeam(int teamID);
        #endregion

        #region [ Dashboard ]

        /// <summary>
        /// Copies the dashboard layout.
        /// </summary>
        /// <param name="userProfileID">The user profile ID.</param>
        /// <param name="userID">The user ID.</param>
        //// public abstract void CopyDashboardLayout(int userProfileID, int userID);
        #endregion

        #region [ Tabs ]
        /// <summary>
		/// Gets the tabs for specified user.
		/// </summary>
		/// <param name="user">The specified user.</param>
		/// <returns>List of tabs for specified user.</returns>
		public abstract IList<WidgetTab> GetTabs(User user);

		/// <summary>
		/// Sets the tab active.
		/// </summary>
		/// <param name="tab">The tab to be set as active.</param>
		/// <param name="user">The user that is related.</param>
		public abstract void SetTabActive(WidgetTab tab, User user);

		/// <summary>
		/// Gets the active tab.
		/// </summary>
		/// <param name="user">The logged user.</param>
		/// <returns>Active tab for logged user.</returns>
		public abstract WidgetTab GetActiveTab(User user);

		/// <summary>
		/// Gets the tab for the specified column.
		/// </summary>
		/// <param name="column">The column.</param>
		/// <returns>Tab that contains specified column.</returns>
		public abstract WidgetTab GetTab(WidgetColumn column);

		/// <summary>
		/// Creates the tab for specified user
		/// </summary>
		/// <param name="tabName">Name of the tab.</param>
		/// <param name="user">The user.</param>
		/// <param name="order">The order.</param>
        public abstract void CreateTab(string tabName, User user, int order);

		/// <summary>
		/// Deletes the tab for specified user
		/// </summary>
		/// <param name="tab">The tab.</param>
        public abstract void DeleteTab(WidgetTab tab);

        /// <summary>
        /// Fixes the order of tabs after deleting tab.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="deletedTabID">The deleted tab ID.</param>
        public abstract void FixOrder(int userID, int deletedTabID);

        /// <summary>
        /// Renames the specified widget tab.
        /// </summary>
        /// <param name="widgetTab">The widget tab.</param>
        public abstract void Rename(WidgetTab widgetTab);

        /// <summary>
        /// Gets the tabs for profile.
        /// </summary>
        /// <param name="userProfileID">The user profile ID.</param>
        /// <returns>Tabs to be copied</returns>
        public abstract IList<WidgetTab> GetTabsForProfile(int userProfileID);

        /// <summary>
        /// Copies the tab for user.
        /// </summary>
        /// <param name="tab">The tab.</param>
        /// <param name="userID">The user ID.</param>
        /// <returns>ID of created tab</returns>
        public abstract int CopyTabForUser(WidgetTab tab, int userID);
		#endregion

		#region [ Columns ]
		/// <summary>
		/// Gets the columns for the specified tab.
		/// </summary>
		/// <param name="tab">The specified tab.</param>
		/// <returns>List of columns for the specified tab.</returns>
		public abstract IList<WidgetColumn> GetColumns(WidgetTab tab);

        /// <summary>
        /// Gets the column for specified widget
        /// </summary>
        /// <param name="widget">The widget.</param>
        /// <returns>column which contains specified widget</returns>
        public abstract WidgetColumn GetColumn(Widget widget);

        /// <summary>
        /// Deletes the column.
        /// </summary>
        /// <param name="widgetColumn">The widget column to be deleted.</param>
        public abstract void DeleteColumn(WidgetColumn widgetColumn);

		/// <summary>
		/// Adds the column into widget (as last one, counting from left to right)
		/// </summary>
		/// <param name="widgetColumn">The widget column.</param>
		/// <param name="tab">The tab.</param>
		/// <param name="before">if set to <c>true</c> [before].</param>
        public abstract void AddColumn(WidgetColumn widgetColumn, WidgetTab tab, bool before);

		/// <summary>
		/// Changes the order of the widget in column.
		/// </summary>
		/// <param name="widget">Widget to change order</param>
		/// <param name="up">Direction, if true then increase order, else decrease</param>
        public abstract void ChangeWidgetOrder(Widget widget, bool up);

        /// <summary>
        /// Copies the columns for tab.
        /// </summary>
        /// <param name="column">The columns.</param>
        /// <param name="tabID">The tab ID.</param>
        /// <returns>ID of created column</returns>
        public abstract int CopyColumnForTab(WidgetColumn column, int tabID);

		#endregion

	    #region [ Attachment ]
        	/// <summary>
       		/// Gets all attachments for the specified userStory.
        	/// </summary>
        	/// <param name="userStoryID">The specific ID of UserStory.</param>\
        	/// <returns>List of attachments for Userstory</returns>
        	public abstract List<Attachment> GetAttachmetnsForUserStory(int userStoryID);

        	#endregion

        #region [ DailyScrum ]

        /// <summary>
        /// Returns all deatils of daily scrum meetings for user
        /// </summary>
        /// <param name="user">Specific user</param>
        /// <returns>List of daily scrum details</returns>
        public abstract List<DailyScrum> GetAlldailyScrumDetails(User user);

        /// <summary>
        /// Creates new DailyScrum detail
        /// </summary>
        /// <param name="ds">DailyScrum to create</param>
        /// <returns>Created DailyScrum with ID set</returns>
        public abstract DailyScrum CreateNewDailyScrumDetail(DailyScrum ds);

        /// <summary>
        /// Updates DailyScrum
        /// </summary>
        /// <param name="ds">Daily scrum to update</param>
        public abstract void UpdateDailyScrum(DailyScrum ds);

		/// <summary>
		/// Deletes daily scrum detail entry
		/// </summary>
		/// <param name="dailyScrumID">The daily scrum ID.</param>
        public abstract void DeleteDailyScrum(int dailyScrumID);
        #endregion

        #region [ Burndownchart ]

        /// <summary>
        /// Gets the progress for sprint.
        /// </summary>
        /// <param name="sprintID">The sprint ID.</param>
        /// <returns></returns>
        public abstract IList<DailyWorkProgress> GetProgressForSprint(int sprintID);

        #endregion

        #region [ Comments ]
        /// <summary>
        /// Returns all threads for specific entity
        /// </summary>
        /// <param name="entityID">ID of entity</param>
        /// <param name="type">Type of entity, task, bli, userstory, ...</param>
        /// <returns>List of threads</returns>
        public abstract List<Thread> GetAllThreadsForEntity(int entityID, string type);

		/// <summary>
		/// Gets Thread object asociated with specified ID
		/// </summary>
		/// <param name="id">The id.</param>
		/// <returns>Thread object</returns>
        public abstract Thread GetThreadByID(int id);

        /// <summary>
        /// Gets all comments for specific thread
        /// </summary>
        /// <param name="threadID">ID of thread</param>
        /// <returns>List of comments for specified thread</returns>
        public abstract List<Comment> GetAllCommentsForThread(int threadID);

        /// <summary>
        /// Returns all subcomments for comment
        /// </summary>
        /// <param name="id">Id of comment</param>
        /// <returns>List of sub comments</returns>
        public abstract List<Comment> GetSubCommentsForComment(int id);

        /// <summary>
        /// Creates new thread for entity
        /// </summary>
        /// <param name="thread">Thread to insert</param>
        /// <returns>Created thread with id</returns>
        public abstract Thread CreateNewThread(Thread thread);

		/// <summary>
		/// Creates new comment for entity
		/// </summary>
		/// <param name="comment">Comment to insert</param>
		/// <param name="inComment">The in comment.</param>
		/// <returns>Created comment with id</returns>
        public abstract Comment CreateNewComment(Comment comment, int inComment);

		/// <summary>
		/// Updates thread
		/// </summary>
		/// <param name="thread">Thread to update</param>
        public abstract void UpdateThread(Thread thread);

        /// <summary>
        /// Deletes thread
        /// </summary>
        /// <param name="threadID">ID of Thread to delete</param>
        public abstract void DeleteThread(int threadID);

        /// <summary>
        /// Updates comment
        /// </summary>
        /// <param name="comment">Comment to update</param>
        /// <param name="inComment">Parent Comment</param>
        public abstract void UpdateComment(Comment comment, int inComment);

        /// <summary>
        /// Deletes comment
        /// </summary>
        /// <param name="commentID">ID of Comment to delete</param>
        public abstract void DeleteComment(int commentID);

        /// <summary>
        /// Gets Comment object asociated with specified ID
        /// </summary>
        /// <param name="id">ID of Comment</param>
        /// <returns>Comment object</returns>
        public abstract Comment GetCommentByID(int id);

		/// <summary>
		/// Gets all Comments object asociated with specified ID of entity
		/// </summary>
		/// <param name="id">ID of Entity</param>
		/// <param name="type">Type of entity</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<Comment> GetCommentsForEntity(int id, string type);
        #endregion

        #region [ Work progress ]
		/// <summary>
		/// Gets the work progress for user.
		/// </summary>
		/// <param name="userID">The user ID.</param>
		/// <param name="from">Date specifiing filter from.</param>
		/// <param name="to">Date specifiing filter to.</param>
		/// <returns>
		/// A list containing all the elements that match the conditions defined by the specified parameters.
		/// </returns>
        public abstract IList<WorkProgress> GetProgressForUser(int userID, DateTime from, DateTime to);

        /// <summary>
        /// Adds the work progress.
        /// </summary>
        /// <param name="userID">The user ID.</param>
        /// <param name="taskID">The task ID.</param>
        /// <param name="date">The date.</param>
        /// <param name="storyPoints">The story points.</param>
        /// <param name="note">The note.</param>
        public abstract void AddWorkProgress(int userID, int taskID, DateTime date, double storyPoints, string note);

		/// <summary>
		/// Deletes the work progress.
		/// </summary>
		/// <param name="progressID">The progress ID.</param>
		public abstract void DeleteWorkProgress(int progressID);

		/// <summary>
		/// Edits the work progress.
		/// </summary>
		/// <param name="workProgress">The work progress.</param>
		public abstract void EditWorkProgress(WorkProgress workProgress);

		/// <summary>
		/// Gets the progress by ID.
		/// </summary>
		/// <param name="progressID">The progress ID.</param>
		/// <returns>Work progress with specified ID.</returns>
		public abstract WorkProgress GetProgressByID(int progressID);
        #endregion

        #region[ Availability ]
        /// <summary>
        /// Gets all availability records for specific team in defined time range
        /// </summary>
        /// <param name="teamID">ID of team</param>
        /// <param name="from">Start date</param>
        /// <param name="to">End date</param>
        /// <returns>Availability records for team</returns>
        public abstract List<Availability> GetAvailabilityForTeam(int teamID, DateTime from, DateTime to);

        /// <summary>
        /// Gets all availability records for specific user in defined time range
        /// </summary>
        /// <param name="userID">ID of user</param>
        /// <param name="from">Start date</param>
        /// <param name="to">End date</param>
        /// <returns>Availability records for user</returns>
        public abstract List<Availability> GetAvailabilityForUser(int userID, DateTime from, DateTime to);

        /// <summary>
        /// Gets all availability records in defined time range
        /// </summary>
        /// <param name="from">Start date</param>
        /// <param name="to">End date</param>
        /// <returns>Availability records </returns>
        public abstract List<Availability> GetAvailabilities(DateTime from, DateTime to);

        /// <summary>
        /// Returns availability according to specified ID
        /// </summary>
        /// <param name="id">ID of availability</param>
        /// <returns>The Availability</returns>
        public abstract Availability GetAvailabilityByID(int id);

		/// <summary>
		/// Creates new instance of availability
		/// </summary>
		/// <param name="availability">Availability to be created</param>
		/// <returns>Created availability</returns>
        public abstract Availability CreateAvailability(Availability availability);

		/// <summary>
		/// Updates Availability
		/// </summary>
		/// <param name="availability">Availability to be updated</param>
        public abstract void UpdateAvailability(Availability availability);

        /// <summary>
        /// Deletes specific availability
        /// </summary>
        /// <param name="id">ID of availability</param>
        public abstract void DeleteAvailability(int id);
        #endregion

		#region [ User settings ]
		/// <summary>
		/// Gets the settings for user.
		/// </summary>
		/// <param name="userID">The user ID.</param>
		/// <returns>User settings for user with specified ID.</returns>
		public abstract UserSettings GetSettingsForUser(int userID);

		/// <summary>
		/// Creates the default settings.
		/// </summary>
		/// <param name="userID">The user ID.</param>
		public abstract void CreateDefaultSettings(int userID);

		/// <summary>
		/// Updates the settings for logged user.
		/// </summary>
		/// <param name="userID">The user ID.</param>
		/// <param name="us">The user settings.</param>
		public abstract void UpdateSettingsForLoggedUser(int userID, UserSettings us);
		#endregion
	}
}
